using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.ComponentModel;
using System.Collections;
using System.Collections.Generic;

namespace WeifenLuo.WinFormsUI.Docking
{
    internal class VS2005DockPaneStrip : DockPaneStripBase
    {
        private class TabVS2005 : Tab
        {
            public TabVS2005( IDockContent content )
                : base( content )
            {
            }

            private int m_tabX;
            public int TabX
            {
                get { return m_tabX; }
                set { m_tabX = value; }
            }

            private int m_tabWidth;
            public int TabWidth
            {
                get { return m_tabWidth; }
                set { m_tabWidth = value; }
            }

            private int m_maxWidth;
            public int MaxWidth
            {
                get { return m_maxWidth; }
                set { m_maxWidth = value; }
            }

            private bool m_flag;
            protected internal bool Flag
            {
                get { return m_flag; }
                set { m_flag = value; }
            }
        }

        protected internal override DockPaneStripBase.Tab CreateTab( IDockContent content )
        {
            return new TabVS2005( content );
        }

        private sealed class InertButton : InertButtonBase
        {
            private Bitmap m_image0, m_image1;

            public InertButton( Bitmap image0, Bitmap image1 )
                : base()
            {
                m_image0 = image0;
                m_image1 = image1;
            }

            private int m_imageCategory = 0;
            public int ImageCategory
            {
                get { return m_imageCategory; }
                set
                {
                    if ( m_imageCategory == value )
                        return;

                    m_imageCategory = value;
                    Invalidate();
                }
            }

            public override Bitmap Image
            {
                get { return ImageCategory == 0 ? m_image0 : m_image1; }
            }
        }

        #region Constants

        private const int _ToolWindowStripGapTop = 0;
        private const int _ToolWindowStripGapBottom = 1;
        private const int _ToolWindowStripGapLeft = 0;
        private const int _ToolWindowStripGapRight = 0;
        private const int _ToolWindowImageHeight = 16;
        private const int _ToolWindowImageWidth = 16;
        private const int _ToolWindowImageGapTop = 3;
        private const int _ToolWindowImageGapBottom = 1;
        private const int _ToolWindowImageGapLeft = 2;
        private const int _ToolWindowImageGapRight = 0;
        private const int _ToolWindowTextGapRight = 3;
        private const int _ToolWindowTabSeperatorGapTop = 3;
        private const int _ToolWindowTabSeperatorGapBottom = 3;

        private const int _DocumentStripGapTop = 0;
        private const int _DocumentStripGapBottom = 1;
        private const int _DocumentTabMaxWidth = 200;
        private const int _DocumentButtonGapTop = 4;
        private const int _DocumentButtonGapBottom = 4;
        private const int _DocumentButtonGapBetween = 0;
        private const int _DocumentButtonGapRight = 3;
        private const int _DocumentTabGapTop = 1;
        private const int _DocumentTabGapLeft = 3;
        private const int _DocumentTabGapRight = 3;
        private const int _DocumentIconGapBottom = 2;
        private const int _DocumentIconGapLeft = 10;
        private const int _DocumentIconGapRight = 0;
        private const int _DocumentIconHeight = 16;
        private const int _DocumentIconWidth = 16;
        private const int _DocumentTextGapRight = 3;

        #endregion

        #region Members

        private ContextMenuStrip m_selectMenu;
        private static Bitmap m_imageButtonClose;
        private InertButton m_buttonClose;
        private static Bitmap m_imageButtonWindowList;
        private static Bitmap m_imageButtonWindowListOverflow;
        private InertButton m_buttonWindowList;
        private IContainer m_components;
        private ToolTip m_toolTip;
        private Font m_font;
        private Font m_boldFont;
        private int m_startDisplayingTab = 0;
        private int m_endDisplayingTab = 0;
        private int m_firstDisplayingTab = 0;
        private bool m_documentTabsOverflow = false;
        private static string m_toolTipSelect;
        private static string m_toolTipClose;
        private bool m_closeButtonVisible = false;

        #endregion

        #region Properties

        private Rectangle TabStripRectangle
        {
            get
            {
                if ( Appearance == DockPane.AppearanceStyle.Document )
                    return TabStripRectangle_Document;
                else
                    return TabStripRectangle_ToolWindow;
            }
        }

        private Rectangle TabStripRectangle_ToolWindow
        {
            get
            {
                Rectangle rect = ClientRectangle;
                return new Rectangle( rect.X, rect.Top + ToolWindowStripGapTop, rect.Width, rect.Height - ToolWindowStripGapTop - ToolWindowStripGapBottom );
            }
        }

        private Rectangle TabStripRectangle_Document
        {
            get
            {
                Rectangle rect = ClientRectangle;
                return new Rectangle( rect.X, rect.Top + DocumentStripGapTop, rect.Width, rect.Height - DocumentStripGapTop - ToolWindowStripGapBottom );
            }
        }

        private Rectangle TabsRectangle
        {
            get
            {
                if ( Appearance == DockPane.AppearanceStyle.ToolWindow )
                    return TabStripRectangle;

                Rectangle rectWindow = TabStripRectangle;
                int x = rectWindow.X;
                int y = rectWindow.Y;
                int width = rectWindow.Width;
                int height = rectWindow.Height;

                x += DocumentTabGapLeft;
                width -= DocumentTabGapLeft +
                    DocumentTabGapRight +
                    DocumentButtonGapRight +
                    ButtonClose.Width +
                    ButtonWindowList.Width +
                    2 * DocumentButtonGapBetween;

                return new Rectangle( x, y, width, height );
            }
        }

        private ContextMenuStrip SelectMenu
        {
            get { return m_selectMenu; }
        }

        private static Bitmap ImageButtonClose
        {
            get
            {
                if ( m_imageButtonClose == null )
                    m_imageButtonClose = Resources.DockPane_Close;

                return m_imageButtonClose;
            }
        }

        private InertButton ButtonClose
        {
            get
            {
                if ( m_buttonClose == null )
                {
                    m_buttonClose = new InertButton( ImageButtonClose, ImageButtonClose );
                    m_toolTip.SetToolTip( m_buttonClose, ToolTipClose );
                    m_buttonClose.Click += new EventHandler( Close_Click );
                    Controls.Add( m_buttonClose );
                }

                return m_buttonClose;
            }
        }

        private static Bitmap ImageButtonWindowList
        {
            get
            {
                if ( m_imageButtonWindowList == null )
                    m_imageButtonWindowList = Resources.DockPane_Option;

                return m_imageButtonWindowList;
            }
        }

        private static Bitmap ImageButtonWindowListOverflow
        {
            get
            {
                if ( m_imageButtonWindowListOverflow == null )
                    m_imageButtonWindowListOverflow = Resources.DockPane_OptionOverflow;

                return m_imageButtonWindowListOverflow;
            }
        }

        private InertButton ButtonWindowList
        {
            get
            {
                if ( m_buttonWindowList == null )
                {
                    m_buttonWindowList = new InertButton( ImageButtonWindowList, ImageButtonWindowListOverflow );
                    m_toolTip.SetToolTip( m_buttonWindowList, ToolTipSelect );
                    m_buttonWindowList.Click += new EventHandler( WindowList_Click );
                    Controls.Add( m_buttonWindowList );
                }

                return m_buttonWindowList;
            }
        }

        private static GraphicsPath GraphicsPath
        {
            get { return VS2005AutoHideStrip.GraphicsPath; }
        }

        private IContainer Components
        {
            get { return m_components; }
        }

        public Font TextFont
        {
            get { return DockPane.DockPanel.Skin.DockPaneStripSkin.TextFont; }
        }

        private Font BoldFont
        {
            get
            {
                if ( IsDisposed )
                    return null;

                if ( m_boldFont == null )
                {
                    m_font = TextFont;
                    m_boldFont = new Font( TextFont, FontStyle.Bold );
                }
                else if ( m_font != TextFont )
                {
                    m_boldFont.Dispose();
                    m_font = TextFont;
                    m_boldFont = new Font( TextFont, FontStyle.Bold );
                }

                return m_boldFont;
            }
        }

        private int StartDisplayingTab
        {
            get { return m_startDisplayingTab; }
            set
            {
                m_startDisplayingTab = value;
                Invalidate();
            }
        }

        private int EndDisplayingTab
        {
            get { return m_endDisplayingTab; }
            set { m_endDisplayingTab = value; }
        }

        private int FirstDisplayingTab
        {
            get { return m_firstDisplayingTab; }
            set { m_firstDisplayingTab = value; }
        }

        private bool DocumentTabsOverflow
        {
            set
            {
                if ( m_documentTabsOverflow == value )
                    return;

                m_documentTabsOverflow = value;
                if ( value )
                    ButtonWindowList.ImageCategory = 1;
                else
                    ButtonWindowList.ImageCategory = 0;
            }
        }

        #region Customizable Properties

        private static int ToolWindowStripGapTop
        {
            get { return _ToolWindowStripGapTop; }
        }

        private static int ToolWindowStripGapBottom
        {
            get { return _ToolWindowStripGapBottom; }
        }

        private static int ToolWindowStripGapLeft
        {
            get { return _ToolWindowStripGapLeft; }
        }

        private static int ToolWindowStripGapRight
        {
            get { return _ToolWindowStripGapRight; }
        }

        private static int ToolWindowImageHeight
        {
            get { return _ToolWindowImageHeight; }
        }

        private static int ToolWindowImageWidth
        {
            get { return _ToolWindowImageWidth; }
        }

        private static int ToolWindowImageGapTop
        {
            get { return _ToolWindowImageGapTop; }
        }

        private static int ToolWindowImageGapBottom
        {
            get { return _ToolWindowImageGapBottom; }
        }

        private static int ToolWindowImageGapLeft
        {
            get { return _ToolWindowImageGapLeft; }
        }

        private static int ToolWindowImageGapRight
        {
            get { return _ToolWindowImageGapRight; }
        }

        private static int ToolWindowTextGapRight
        {
            get { return _ToolWindowTextGapRight; }
        }

        private static int ToolWindowTabSeperatorGapTop
        {
            get { return _ToolWindowTabSeperatorGapTop; }
        }

        private static int ToolWindowTabSeperatorGapBottom
        {
            get { return _ToolWindowTabSeperatorGapBottom; }
        }

        private static string ToolTipClose
        {
            get
            {
                if ( m_toolTipClose == null )
                    m_toolTipClose = Strings.DockPaneStrip_ToolTipClose;
                return m_toolTipClose;
            }
        }

        private static string ToolTipSelect
        {
            get
            {
                if ( m_toolTipSelect == null )
                    m_toolTipSelect = Strings.DockPaneStrip_ToolTipWindowList;
                return m_toolTipSelect;
            }
        }

        private TextFormatFlags ToolWindowTextFormat
        {
            get
            {
                TextFormatFlags textFormat = TextFormatFlags.EndEllipsis |
                    TextFormatFlags.HorizontalCenter |
                    TextFormatFlags.SingleLine |
                    TextFormatFlags.VerticalCenter;
                if ( RightToLeft == RightToLeft.Yes )
                    return textFormat | TextFormatFlags.RightToLeft | TextFormatFlags.Right;
                else
                    return textFormat;
            }
        }

        private static int DocumentStripGapTop
        {
            get { return _DocumentStripGapTop; }
        }

        private static int DocumentStripGapBottom
        {
            get { return _DocumentStripGapBottom; }
        }

        private TextFormatFlags DocumentTextFormat
        {
            get
            {
                TextFormatFlags textFormat = TextFormatFlags.EndEllipsis |
                    TextFormatFlags.SingleLine |
                    TextFormatFlags.VerticalCenter |
                    TextFormatFlags.HorizontalCenter;
                if ( RightToLeft == RightToLeft.Yes )
                    return textFormat | TextFormatFlags.RightToLeft;
                else
                    return textFormat;
            }
        }

        private static int DocumentTabMaxWidth
        {
            get { return _DocumentTabMaxWidth; }
        }

        private static int DocumentButtonGapTop
        {
            get { return _DocumentButtonGapTop; }
        }

        private static int DocumentButtonGapBottom
        {
            get { return _DocumentButtonGapBottom; }
        }

        private static int DocumentButtonGapBetween
        {
            get { return _DocumentButtonGapBetween; }
        }

        private static int DocumentButtonGapRight
        {
            get { return _DocumentButtonGapRight; }
        }

        private static int DocumentTabGapTop
        {
            get { return _DocumentTabGapTop; }
        }

        private static int DocumentTabGapLeft
        {
            get { return _DocumentTabGapLeft; }
        }

        private static int DocumentTabGapRight
        {
            get { return _DocumentTabGapRight; }
        }

        private static int DocumentIconGapBottom
        {
            get { return _DocumentIconGapBottom; }
        }

        private static int DocumentIconGapLeft
        {
            get { return _DocumentIconGapLeft; }
        }

        private static int DocumentIconGapRight
        {
            get { return _DocumentIconGapRight; }
        }

        private static int DocumentIconWidth
        {
            get { return _DocumentIconWidth; }
        }

        private static int DocumentIconHeight
        {
            get { return _DocumentIconHeight; }
        }

        private static int DocumentTextGapRight
        {
            get { return _DocumentTextGapRight; }
        }

        private static Pen PenToolWindowTabBorder
        {
            get { return SystemPens.GrayText; }
        }

        private static Pen PenDocumentTabActiveBorder
        {
            get { return SystemPens.ControlDarkDark; }
        }

        private static Pen PenDocumentTabInactiveBorder
        {
            get { return SystemPens.GrayText; }
        }

        #endregion

        #endregion

        public VS2005DockPaneStrip( DockPane pane )
            : base( pane )
        {
            SetStyle( ControlStyles.ResizeRedraw |
                ControlStyles.UserPaint |
                ControlStyles.AllPaintingInWmPaint |
                ControlStyles.OptimizedDoubleBuffer, true );

            SuspendLayout();

            m_components = new Container();
            m_toolTip = new ToolTip( Components );
            m_selectMenu = new ContextMenuStrip( Components );

            ResumeLayout();
        }

        protected override void Dispose( bool disposing )
        {
            if ( disposing )
            {
                Components.Dispose();
                if ( m_boldFont != null )
                {
                    m_boldFont.Dispose();
                    m_boldFont = null;
                }
            }
            base.Dispose( disposing );
        }

        protected internal override int MeasureHeight()
        {
            if ( Appearance == DockPane.AppearanceStyle.ToolWindow )
                return MeasureHeight_ToolWindow();
            else
                return MeasureHeight_Document();
        }

        private int MeasureHeight_ToolWindow()
        {
            if ( DockPane.IsAutoHide || Tabs.Count <= 1 )
                return 0;

            int height = Math.Max( TextFont.Height, ToolWindowImageHeight + ToolWindowImageGapTop + ToolWindowImageGapBottom )
                + ToolWindowStripGapTop + ToolWindowStripGapBottom;

            return height;
        }

        private int MeasureHeight_Document()
        {
            int height = Math.Max( TextFont.Height + DocumentTabGapTop,
                ButtonClose.Height + DocumentButtonGapTop + DocumentButtonGapBottom )
                + DocumentStripGapBottom + DocumentStripGapTop;

            return height;
        }

        protected override void OnPaint( PaintEventArgs e )
        {
            Rectangle rect = TabsRectangle;

            if ( Appearance == DockPane.AppearanceStyle.Document )
            {
                rect.X -= DocumentTabGapLeft;

                // Add these values back in so that the DockStrip color is drawn
                // beneath the close button and window list button.
                rect.Width += DocumentTabGapLeft +
                    DocumentTabGapRight +
                    DocumentButtonGapRight +
                    ButtonClose.Width +
                    ButtonWindowList.Width;

                // It is possible depending on the DockPanel DocumentStyle to have
                // a Document without a DockStrip.
                if ( rect.Width > 0 && rect.Height > 0 )
                {
                    Color startColor = DockPane.DockPanel.Skin.DockPaneStripSkin.DocumentGradient.DockStripGradient.StartColor;
                    Color endColor = DockPane.DockPanel.Skin.DockPaneStripSkin.DocumentGradient.DockStripGradient.EndColor;
                    LinearGradientMode gradientMode = DockPane.DockPanel.Skin.DockPaneStripSkin.DocumentGradient.DockStripGradient.LinearGradientMode;
                    using ( LinearGradientBrush brush = new LinearGradientBrush( rect, startColor, endColor, gradientMode ) )
                    {
                        e.Graphics.FillRectangle( brush, rect );
                    }
                }
            }
            else
            {
                Color startColor = DockPane.DockPanel.Skin.DockPaneStripSkin.ToolWindowGradient.DockStripGradient.StartColor;
                Color endColor = DockPane.DockPanel.Skin.DockPaneStripSkin.ToolWindowGradient.DockStripGradient.EndColor;
                LinearGradientMode gradientMode = DockPane.DockPanel.Skin.DockPaneStripSkin.ToolWindowGradient.DockStripGradient.LinearGradientMode;
                using ( LinearGradientBrush brush = new LinearGradientBrush( rect, startColor, endColor, gradientMode ) )
                {
                    e.Graphics.FillRectangle( brush, rect );
                }
            }
            base.OnPaint( e );
            CalculateTabs();
            if ( Appearance == DockPane.AppearanceStyle.Document && DockPane.ActiveContent != null )
            {
                if ( EnsureDocumentTabVisible( DockPane.ActiveContent, false ) )
                    CalculateTabs();
            }

            DrawTabStrip( e.Graphics );
        }

        protected override void OnRefreshChanges()
        {
            SetInertButtons();
            Invalidate();
        }

        protected internal override GraphicsPath GetOutline( int index )
        {

            if ( Appearance == DockPane.AppearanceStyle.Document )
                return GetOutline_Document( index );
            else
                return GetOutline_ToolWindow( index );

        }

        private GraphicsPath GetOutline_Document( int index )
        {
            Rectangle rectTab = GetTabRectangle( index );
            rectTab.X -= rectTab.Height / 2;
            rectTab.Intersect( TabsRectangle );
            rectTab = RectangleToScreen( DrawHelper.RtlTransform( this, rectTab ) );
            Rectangle rectPaneClient = DockPane.RectangleToScreen( DockPane.ClientRectangle );

            GraphicsPath path = new GraphicsPath();
            GraphicsPath pathTab = GetTabOutline_Document( Tabs[ index ], true, true, true );
            path.AddPath( pathTab, true );

            if ( DockPane.DockPanel.DocumentTabStripLocation == DocumentTabStripLocation.Bottom )
            {
                path.AddLine( rectTab.Right, rectTab.Top, rectPaneClient.Right, rectTab.Top );
                path.AddLine( rectPaneClient.Right, rectTab.Top, rectPaneClient.Right, rectPaneClient.Top );
                path.AddLine( rectPaneClient.Right, rectPaneClient.Top, rectPaneClient.Left, rectPaneClient.Top );
                path.AddLine( rectPaneClient.Left, rectPaneClient.Top, rectPaneClient.Left, rectTab.Top );
                path.AddLine( rectPaneClient.Left, rectTab.Top, rectTab.Right, rectTab.Top );
            }
            else
            {
                path.AddLine( rectTab.Right, rectTab.Bottom, rectPaneClient.Right, rectTab.Bottom );
                path.AddLine( rectPaneClient.Right, rectTab.Bottom, rectPaneClient.Right, rectPaneClient.Bottom );
                path.AddLine( rectPaneClient.Right, rectPaneClient.Bottom, rectPaneClient.Left, rectPaneClient.Bottom );
                path.AddLine( rectPaneClient.Left, rectPaneClient.Bottom, rectPaneClient.Left, rectTab.Bottom );
                path.AddLine( rectPaneClient.Left, rectTab.Bottom, rectTab.Right, rectTab.Bottom );
            }
            return path;
        }

        private GraphicsPath GetOutline_ToolWindow( int index )
        {
            Rectangle rectTab = GetTabRectangle( index );
            rectTab.Intersect( TabsRectangle );
            rectTab = RectangleToScreen( DrawHelper.RtlTransform( this, rectTab ) );
            Rectangle rectPaneClient = DockPane.RectangleToScreen( DockPane.ClientRectangle );

            GraphicsPath path = new GraphicsPath();
            GraphicsPath pathTab = GetTabOutline( Tabs[ index ], true, true );
            path.AddPath( pathTab, true );
            path.AddLine( rectTab.Left, rectTab.Top, rectPaneClient.Left, rectTab.Top );
            path.AddLine( rectPaneClient.Left, rectTab.Top, rectPaneClient.Left, rectPaneClient.Top );
            path.AddLine( rectPaneClient.Left, rectPaneClient.Top, rectPaneClient.Right, rectPaneClient.Top );
            path.AddLine( rectPaneClient.Right, rectPaneClient.Top, rectPaneClient.Right, rectTab.Top );
            path.AddLine( rectPaneClient.Right, rectTab.Top, rectTab.Right, rectTab.Top );
            return path;
        }

        private void CalculateTabs()
        {
            if ( Appearance == DockPane.AppearanceStyle.ToolWindow )
                CalculateTabs_ToolWindow();
            else
                CalculateTabs_Document();
        }

        private void CalculateTabs_ToolWindow()
        {
            if ( Tabs.Count <= 1 || DockPane.IsAutoHide )
                return;

            Rectangle rectTabStrip = TabStripRectangle;

            // Calculate tab widths
            int countTabs = Tabs.Count;
            foreach ( TabVS2005 tab in Tabs )
            {
                tab.MaxWidth = GetMaxTabWidth( Tabs.IndexOf( tab ) );
                tab.Flag = false;
            }

            // Set tab whose max width less than average width
            bool anyWidthWithinAverage = true;
            int totalWidth = rectTabStrip.Width - ToolWindowStripGapLeft - ToolWindowStripGapRight;
            int totalAllocatedWidth = 0;
            int averageWidth = totalWidth / countTabs;
            int remainedTabs = countTabs;
            for ( anyWidthWithinAverage = true; anyWidthWithinAverage && remainedTabs > 0; )
            {
                anyWidthWithinAverage = false;
                foreach ( TabVS2005 tab in Tabs )
                {
                    if ( tab.Flag )
                        continue;

                    if ( tab.MaxWidth <= averageWidth )
                    {
                        tab.Flag = true;
                        tab.TabWidth = tab.MaxWidth;
                        totalAllocatedWidth += tab.TabWidth;
                        anyWidthWithinAverage = true;
                        remainedTabs--;
                    }
                }
                if ( remainedTabs != 0 )
                    averageWidth = ( totalWidth - totalAllocatedWidth ) / remainedTabs;
            }

            // If any tab width not set yet, set it to the average width
            if ( remainedTabs > 0 )
            {
                int roundUpWidth = ( totalWidth - totalAllocatedWidth ) - ( averageWidth * remainedTabs );
                foreach ( TabVS2005 tab in Tabs )
                {
                    if ( tab.Flag )
                        continue;

                    tab.Flag = true;
                    if ( roundUpWidth > 0 )
                    {
                        tab.TabWidth = averageWidth + 1;
                        roundUpWidth--;
                    }
                    else
                        tab.TabWidth = averageWidth;
                }
            }

            // Set the X position of the tabs
            int x = rectTabStrip.X + ToolWindowStripGapLeft;
            foreach ( TabVS2005 tab in Tabs )
            {
                tab.TabX = x;
                x += tab.TabWidth;
            }
        }

        private bool CalculateDocumentTab( Rectangle rectTabStrip, ref int x, int index )
        {
            bool overflow = false;

            TabVS2005 tab = Tabs[ index ] as TabVS2005;
            tab.MaxWidth = GetMaxTabWidth( index );
            int width = Math.Min( tab.MaxWidth, DocumentTabMaxWidth );
            if ( x + width < rectTabStrip.Right || index == StartDisplayingTab )
            {
                tab.TabX = x;
                tab.TabWidth = width;
                EndDisplayingTab = index;
            }
            else
            {
                tab.TabX = 0;
                tab.TabWidth = 0;
                overflow = true;
            }
            x += width;

            return overflow;
        }

        /// <summary>
        /// Calculate which tabs are displayed and in what order.
        /// </summary>
        private void CalculateTabs_Document()
        {
            if ( m_startDisplayingTab >= Tabs.Count )
                m_startDisplayingTab = 0;

            Rectangle rectTabStrip = TabsRectangle;

            int x = rectTabStrip.X + rectTabStrip.Height / 2;
            bool overflow = false;

            // Originally all new documents that were considered overflow
            // (not enough pane strip space to show all tabs) were added to
            // the far left (assuming not right to left) and the tabs on the
            // right were dropped from view. If StartDisplayingTab is not 0
            // then we are dealing with making sure a specific tab is kept in focus.
            if ( m_startDisplayingTab > 0 )
            {
                int tempX = x;
                TabVS2005 tab = Tabs[ m_startDisplayingTab ] as TabVS2005;
                tab.MaxWidth = GetMaxTabWidth( m_startDisplayingTab );

                // Add the active tab and tabs to the left
                for ( int i = StartDisplayingTab; i >= 0; i-- )
                    CalculateDocumentTab( rectTabStrip, ref tempX, i );

                // Store which tab is the first one displayed so that it
                // will be drawn correctly (without part of the tab cut off)
                FirstDisplayingTab = EndDisplayingTab;

                tempX = x; // Reset X location because we are starting over

                // Start with the first tab displayed - name is a little misleading.
                // Loop through each tab and set its location. If there is not enough
                // room for all of them overflow will be returned.
                for ( int i = EndDisplayingTab; i < Tabs.Count; i++ )
                    overflow = CalculateDocumentTab( rectTabStrip, ref tempX, i );

                // If not all tabs are shown then we have an overflow.
                if ( FirstDisplayingTab != 0 )
                    overflow = true;
            }
            else
            {
                for ( int i = StartDisplayingTab; i < Tabs.Count; i++ )
                    overflow = CalculateDocumentTab( rectTabStrip, ref x, i );
                for ( int i = 0; i < StartDisplayingTab; i++ )
                    overflow = CalculateDocumentTab( rectTabStrip, ref x, i );

                FirstDisplayingTab = StartDisplayingTab;
            }

            if ( !overflow )
            {
                m_startDisplayingTab = 0;
                FirstDisplayingTab = 0;
                x = rectTabStrip.X + rectTabStrip.Height / 2;
                foreach ( TabVS2005 tab in Tabs )
                {
                    tab.TabX = x;
                    x += tab.TabWidth;
                }
            }
            DocumentTabsOverflow = overflow;
        }

        protected internal override void EnsureTabVisible( IDockContent content )
        {
            if ( Appearance != DockPane.AppearanceStyle.Document || !Tabs.Contains( content ) )
                return;

            CalculateTabs();
            EnsureDocumentTabVisible( content, true );
        }

        private bool EnsureDocumentTabVisible( IDockContent content, bool repaint )
        {
            int index = Tabs.IndexOf( content );
            TabVS2005 tab = Tabs[ index ] as TabVS2005;
            if ( tab.TabWidth != 0 )
                return false;

            StartDisplayingTab = index;
            if ( repaint )
                Invalidate();

            return true;
        }

        private int GetMaxTabWidth( int index )
        {
            if ( Appearance == DockPane.AppearanceStyle.ToolWindow )
                return GetMaxTabWidth_ToolWindow( index );
            else
                return GetMaxTabWidth_Document( index );
        }

        private int GetMaxTabWidth_ToolWindow( int index )
        {
            IDockContent content = Tabs[ index ].Content;
            Size sizeString = TextRenderer.MeasureText( content.DockHandler.TabText, TextFont );
            return ToolWindowImageWidth + sizeString.Width + ToolWindowImageGapLeft
                + ToolWindowImageGapRight + ToolWindowTextGapRight;
        }

        private int GetMaxTabWidth_Document( int index )
        {
            IDockContent content = Tabs[ index ].Content;

            int height = GetTabRectangle_Document( index ).Height;

            Size sizeText = TextRenderer.MeasureText( content.DockHandler.TabText, BoldFont, new Size( DocumentTabMaxWidth, height ), DocumentTextFormat );

            if ( DockPane.DockPanel.ShowDocumentIcon )
                return sizeText.Width + DocumentIconWidth + DocumentIconGapLeft + DocumentIconGapRight + DocumentTextGapRight;
            else
                return sizeText.Width + DocumentIconGapLeft + DocumentTextGapRight;
        }

        private void DrawTabStrip( Graphics g )
        {
            if ( Appearance == DockPane.AppearanceStyle.Document )
                DrawTabStrip_Document( g );
            else
                DrawTabStrip_ToolWindow( g );
        }

        private void DrawTabStrip_Document( Graphics g )
        {
            int count = Tabs.Count;
            if ( count == 0 )
                return;

            Rectangle rectTabStrip = TabStripRectangle;

            // Draw the tabs
            Rectangle rectTabOnly = TabsRectangle;
            Rectangle rectTab = Rectangle.Empty;
            TabVS2005 tabActive = null;
            g.SetClip( DrawHelper.RtlTransform( this, rectTabOnly ) );
            for ( int i = 0; i < count; i++ )
            {
                rectTab = GetTabRectangle( i );
                if ( Tabs[ i ].Content == DockPane.ActiveContent )
                {
                    tabActive = Tabs[ i ] as TabVS2005;
                    continue;
                }
                if ( rectTab.IntersectsWith( rectTabOnly ) )
                    DrawTab( g, Tabs[ i ] as TabVS2005, rectTab );
            }

            g.SetClip( rectTabStrip );

            if ( DockPane.DockPanel.DocumentTabStripLocation == DocumentTabStripLocation.Bottom )
                g.DrawLine( PenDocumentTabActiveBorder, rectTabStrip.Left, rectTabStrip.Top + 1,
                    rectTabStrip.Right, rectTabStrip.Top + 1 );
            else
                g.DrawLine( PenDocumentTabActiveBorder, rectTabStrip.Left, rectTabStrip.Bottom - 1,
                    rectTabStrip.Right, rectTabStrip.Bottom - 1 );

            g.SetClip( DrawHelper.RtlTransform( this, rectTabOnly ) );
            if ( tabActive != null )
            {
                rectTab = GetTabRectangle( Tabs.IndexOf( tabActive ) );
                if ( rectTab.IntersectsWith( rectTabOnly ) )
                    DrawTab( g, tabActive, rectTab );
            }
        }

        private void DrawTabStrip_ToolWindow( Graphics g )
        {
            Rectangle rectTabStrip = TabStripRectangle;

            g.DrawLine( PenToolWindowTabBorder, rectTabStrip.Left, rectTabStrip.Top,
                rectTabStrip.Right, rectTabStrip.Top );

            for ( int i = 0; i < Tabs.Count; i++ )
                DrawTab( g, Tabs[ i ] as TabVS2005, GetTabRectangle( i ) );
        }

        private Rectangle GetTabRectangle( int index )
        {
            if ( Appearance == DockPane.AppearanceStyle.ToolWindow )
                return GetTabRectangle_ToolWindow( index );
            else
                return GetTabRectangle_Document( index );
        }

        private Rectangle GetTabRectangle_ToolWindow( int index )
        {
            Rectangle rectTabStrip = TabStripRectangle;

            TabVS2005 tab = (TabVS2005)( Tabs[ index ] );
            return new Rectangle( tab.TabX, rectTabStrip.Y, tab.TabWidth, rectTabStrip.Height );
        }

        private Rectangle GetTabRectangle_Document( int index )
        {
            Rectangle rectTabStrip = TabStripRectangle;
            TabVS2005 tab = (TabVS2005)Tabs[ index ];

            Rectangle rect = new Rectangle();
            rect.X = tab.TabX;
            rect.Width = tab.TabWidth;
            rect.Height = rectTabStrip.Height - DocumentTabGapTop;

            if ( DockPane.DockPanel.DocumentTabStripLocation == DocumentTabStripLocation.Bottom )
                rect.Y = rectTabStrip.Y + DocumentStripGapBottom;
            else
                rect.Y = rectTabStrip.Y + DocumentTabGapTop;

            return rect;
        }

        private void DrawTab( Graphics g, TabVS2005 tab, Rectangle rect )
        {
            if ( Appearance == DockPane.AppearanceStyle.ToolWindow )
                DrawTab_ToolWindow( g, tab, rect );
            else
                DrawTab_Document( g, tab, rect );
        }

        private GraphicsPath GetTabOutline( Tab tab, bool rtlTransform, bool toScreen )
        {
            if ( Appearance == DockPane.AppearanceStyle.ToolWindow )
                return GetTabOutline_ToolWindow( tab, rtlTransform, toScreen );
            else
                return GetTabOutline_Document( tab, rtlTransform, toScreen, false );
        }

        private GraphicsPath GetTabOutline_ToolWindow( Tab tab, bool rtlTransform, bool toScreen )
        {
            Rectangle rect = GetTabRectangle( Tabs.IndexOf( tab ) );
            if ( rtlTransform )
                rect = DrawHelper.RtlTransform( this, rect );
            if ( toScreen )
                rect = RectangleToScreen( rect );

            DrawHelper.GetRoundedCornerTab( GraphicsPath, rect, false );
            return GraphicsPath;
        }

        private GraphicsPath GetTabOutline_Document( Tab tab, bool rtlTransform, bool toScreen, bool full )
        {
            int curveSize = 6;

            GraphicsPath.Reset();
            Rectangle rect = GetTabRectangle( Tabs.IndexOf( tab ) );
            if ( rtlTransform )
                rect = DrawHelper.RtlTransform( this, rect );
            if ( toScreen )
                rect = RectangleToScreen( rect );

            // Draws the full angle piece for active content (or first tab)
            if ( tab.Content == DockPane.ActiveContent || full || Tabs.IndexOf( tab ) == FirstDisplayingTab )
            {
                if ( RightToLeft == RightToLeft.Yes )
                {
                    if ( DockPane.DockPanel.DocumentTabStripLocation == DocumentTabStripLocation.Bottom )
                    {
                        // For some reason the next line draws a line that is not hidden like it is when drawing the tab strip on top.
                        // It is not needed so it has been commented out.
                        //GraphicsPath.AddLine(rect.Right, rect.Bottom, rect.Right + rect.Height / 2, rect.Bottom);
                        GraphicsPath.AddLine( rect.Right + rect.Height / 2, rect.Top, rect.Right - rect.Height / 2 + curveSize / 2, rect.Bottom - curveSize / 2 );
                    }
                    else
                    {
                        GraphicsPath.AddLine( rect.Right, rect.Bottom, rect.Right + rect.Height / 2, rect.Bottom );
                        GraphicsPath.AddLine( rect.Right + rect.Height / 2, rect.Bottom, rect.Right - rect.Height / 2 + curveSize / 2, rect.Top + curveSize / 2 );
                    }
                }
                else
                {
                    if ( DockPane.DockPanel.DocumentTabStripLocation == DocumentTabStripLocation.Bottom )
                    {
                        // For some reason the next line draws a line that is not hidden like it is when drawing the tab strip on top.
                        // It is not needed so it has been commented out.
                        //GraphicsPath.AddLine(rect.Left, rect.Top, rect.Left - rect.Height / 2, rect.Top);
                        GraphicsPath.AddLine( rect.Left - rect.Height / 2, rect.Top, rect.Left + rect.Height / 2 - curveSize / 2, rect.Bottom - curveSize / 2 );
                    }
                    else
                    {
                        GraphicsPath.AddLine( rect.Left, rect.Bottom, rect.Left - rect.Height / 2, rect.Bottom );
                        GraphicsPath.AddLine( rect.Left - rect.Height / 2, rect.Bottom, rect.Left + rect.Height / 2 - curveSize / 2, rect.Top + curveSize / 2 );
                    }
                }
            }
            // Draws the partial angle for non-active content
            else
            {
                if ( RightToLeft == RightToLeft.Yes )
                {
                    if ( DockPane.DockPanel.DocumentTabStripLocation == DocumentTabStripLocation.Bottom )
                    {
                        GraphicsPath.AddLine( rect.Right, rect.Top, rect.Right, rect.Top + rect.Height / 2 );
                        GraphicsPath.AddLine( rect.Right, rect.Top + rect.Height / 2, rect.Right - rect.Height / 2 + curveSize / 2, rect.Bottom - curveSize / 2 );
                    }
                    else
                    {
                        GraphicsPath.AddLine( rect.Right, rect.Bottom, rect.Right, rect.Bottom - rect.Height / 2 );
                        GraphicsPath.AddLine( rect.Right, rect.Bottom - rect.Height / 2, rect.Right - rect.Height / 2 + curveSize / 2, rect.Top + curveSize / 2 );
                    }
                }
                else
                {
                    if ( DockPane.DockPanel.DocumentTabStripLocation == DocumentTabStripLocation.Bottom )
                    {
                        GraphicsPath.AddLine( rect.Left, rect.Top, rect.Left, rect.Top + rect.Height / 2 );
                        GraphicsPath.AddLine( rect.Left, rect.Top + rect.Height / 2, rect.Left + rect.Height / 2 - curveSize / 2, rect.Bottom - curveSize / 2 );
                    }
                    else
                    {
                        GraphicsPath.AddLine( rect.Left, rect.Bottom, rect.Left, rect.Bottom - rect.Height / 2 );
                        GraphicsPath.AddLine( rect.Left, rect.Bottom - rect.Height / 2, rect.Left + rect.Height / 2 - curveSize / 2, rect.Top + curveSize / 2 );
                    }
                }
            }

            if ( RightToLeft == RightToLeft.Yes )
            {
                if ( DockPane.DockPanel.DocumentTabStripLocation == DocumentTabStripLocation.Bottom )
                {
                    // Draws the bottom horizontal line (short side)
                    GraphicsPath.AddLine( rect.Right - rect.Height / 2 - curveSize / 2, rect.Bottom, rect.Left + curveSize / 2, rect.Bottom );

                    // Drawing the rounded corner is not necessary. The path is automatically connected
                    //GraphicsPath.AddArc(new Rectangle(rect.Left, rect.Top, curveSize, curveSize), 180, 90);
                }
                else
                {
                    // Draws the bottom horizontal line (short side)
                    GraphicsPath.AddLine( rect.Right - rect.Height / 2 - curveSize / 2, rect.Top, rect.Left + curveSize / 2, rect.Top );
                    GraphicsPath.AddArc( new Rectangle( rect.Left, rect.Top, curveSize, curveSize ), 180, 90 );
                }
            }
            else
            {
                if ( DockPane.DockPanel.DocumentTabStripLocation == DocumentTabStripLocation.Bottom )
                {
                    // Draws the bottom horizontal line (short side)
                    GraphicsPath.AddLine( rect.Left + rect.Height / 2 + curveSize / 2, rect.Bottom, rect.Right - curveSize / 2, rect.Bottom );

                    // Drawing the rounded corner is not necessary. The path is automatically connected
                    //GraphicsPath.AddArc(new Rectangle(rect.Right - curveSize, rect.Bottom, curveSize, curveSize), 90, -90);
                }
                else
                {
                    // Draws the top horizontal line (short side)
                    GraphicsPath.AddLine( rect.Left + rect.Height / 2 + curveSize / 2, rect.Top, rect.Right - curveSize / 2, rect.Top );

                    // Draws the rounded corner oppposite the angled side
                    GraphicsPath.AddArc( new Rectangle( rect.Right - curveSize, rect.Top, curveSize, curveSize ), -90, 90 );
                }
            }

            if ( Tabs.IndexOf( tab ) != EndDisplayingTab &&
                ( Tabs.IndexOf( tab ) != Tabs.Count - 1 && Tabs[ Tabs.IndexOf( tab ) + 1 ].Content == DockPane.ActiveContent )
                && !full )
            {
                if ( RightToLeft == RightToLeft.Yes )
                {
                    if ( DockPane.DockPanel.DocumentTabStripLocation == DocumentTabStripLocation.Bottom )
                    {
                        GraphicsPath.AddLine( rect.Left, rect.Bottom - curveSize / 2, rect.Left, rect.Bottom - rect.Height / 2 );
                        GraphicsPath.AddLine( rect.Left, rect.Bottom - rect.Height / 2, rect.Left + rect.Height / 2, rect.Top );
                    }
                    else
                    {
                        GraphicsPath.AddLine( rect.Left, rect.Top + curveSize / 2, rect.Left, rect.Top + rect.Height / 2 );
                        GraphicsPath.AddLine( rect.Left, rect.Top + rect.Height / 2, rect.Left + rect.Height / 2, rect.Bottom );
                    }
                }
                else
                {
                    if ( DockPane.DockPanel.DocumentTabStripLocation == DocumentTabStripLocation.Bottom )
                    {
                        GraphicsPath.AddLine( rect.Right, rect.Bottom - curveSize / 2, rect.Right, rect.Bottom - rect.Height / 2 );
                        GraphicsPath.AddLine( rect.Right, rect.Bottom - rect.Height / 2, rect.Right - rect.Height / 2, rect.Top );
                    }
                    else
                    {
                        GraphicsPath.AddLine( rect.Right, rect.Top + curveSize / 2, rect.Right, rect.Top + rect.Height / 2 );
                        GraphicsPath.AddLine( rect.Right, rect.Top + rect.Height / 2, rect.Right - rect.Height / 2, rect.Bottom );
                    }
                }
            }
            else
            {
                // Draw the vertical line opposite the angled side
                if ( RightToLeft == RightToLeft.Yes )
                {
                    if ( DockPane.DockPanel.DocumentTabStripLocation == DocumentTabStripLocation.Bottom )
                        GraphicsPath.AddLine( rect.Left, rect.Bottom - curveSize / 2, rect.Left, rect.Top );
                    else
                        GraphicsPath.AddLine( rect.Left, rect.Top + curveSize / 2, rect.Left, rect.Bottom );
                }
                else
                {
                    if ( DockPane.DockPanel.DocumentTabStripLocation == DocumentTabStripLocation.Bottom )
                        GraphicsPath.AddLine( rect.Right, rect.Bottom - curveSize / 2, rect.Right, rect.Top );
                    else
                        GraphicsPath.AddLine( rect.Right, rect.Top + curveSize / 2, rect.Right, rect.Bottom );
                }
            }

            return GraphicsPath;
        }

        private void DrawTab_ToolWindow( Graphics g, TabVS2005 tab, Rectangle rect )
        {
            Rectangle rectIcon = new Rectangle(
                rect.X + ToolWindowImageGapLeft,
                rect.Y + rect.Height - 1 - ToolWindowImageGapBottom - ToolWindowImageHeight,
                ToolWindowImageWidth, ToolWindowImageHeight );
            Rectangle rectText = rectIcon;
            rectText.X += rectIcon.Width + ToolWindowImageGapRight;
            rectText.Width = rect.Width - rectIcon.Width - ToolWindowImageGapLeft -
                ToolWindowImageGapRight - ToolWindowTextGapRight;

            Rectangle rectTab = DrawHelper.RtlTransform( this, rect );
            rectText = DrawHelper.RtlTransform( this, rectText );
            rectIcon = DrawHelper.RtlTransform( this, rectIcon );
            GraphicsPath path = GetTabOutline( tab, true, false );
            if ( DockPane.ActiveContent == tab.Content )
            {
                Color startColor = DockPane.DockPanel.Skin.DockPaneStripSkin.ToolWindowGradient.ActiveTabGradient.StartColor;
                Color endColor = DockPane.DockPanel.Skin.DockPaneStripSkin.ToolWindowGradient.ActiveTabGradient.EndColor;
                LinearGradientMode gradientMode = DockPane.DockPanel.Skin.DockPaneStripSkin.ToolWindowGradient.ActiveTabGradient.LinearGradientMode;
                g.FillPath( new LinearGradientBrush( rectTab, startColor, endColor, gradientMode ), path );
                g.DrawPath( PenToolWindowTabBorder, path );

                Color textColor = DockPane.DockPanel.Skin.DockPaneStripSkin.ToolWindowGradient.ActiveTabGradient.TextColor;
                TextRenderer.DrawText( g, tab.Content.DockHandler.TabText, TextFont, rectText, textColor, ToolWindowTextFormat );
            }
            else
            {
                Color startColor = DockPane.DockPanel.Skin.DockPaneStripSkin.ToolWindowGradient.InactiveTabGradient.StartColor;
                Color endColor = DockPane.DockPanel.Skin.DockPaneStripSkin.ToolWindowGradient.InactiveTabGradient.EndColor;
                LinearGradientMode gradientMode = DockPane.DockPanel.Skin.DockPaneStripSkin.ToolWindowGradient.InactiveTabGradient.LinearGradientMode;
                g.FillPath( new LinearGradientBrush( rectTab, startColor, endColor, gradientMode ), path );

                if ( Tabs.IndexOf( DockPane.ActiveContent ) != Tabs.IndexOf( tab ) + 1 )
                {
                    Point pt1 = new Point( rect.Right, rect.Top + ToolWindowTabSeperatorGapTop );
                    Point pt2 = new Point( rect.Right, rect.Bottom - ToolWindowTabSeperatorGapBottom );
                    g.DrawLine( PenToolWindowTabBorder, DrawHelper.RtlTransform( this, pt1 ), DrawHelper.RtlTransform( this, pt2 ) );
                }

                Color textColor = DockPane.DockPanel.Skin.DockPaneStripSkin.ToolWindowGradient.InactiveTabGradient.TextColor;
                TextRenderer.DrawText( g, tab.Content.DockHandler.TabText, TextFont, rectText, textColor, ToolWindowTextFormat );
            }

            if ( rectTab.Contains( rectIcon ) )
                g.DrawIcon( tab.Content.DockHandler.Icon, rectIcon );
        }

        private void DrawTab_Document( Graphics g, TabVS2005 tab, Rectangle rect )
        {
            if ( tab.TabWidth == 0 )
                return;

            Rectangle rectIcon = new Rectangle(
                rect.X + DocumentIconGapLeft,
                rect.Y + rect.Height - 1 - DocumentIconGapBottom - DocumentIconHeight,
                DocumentIconWidth, DocumentIconHeight );
            Rectangle rectText = rectIcon;
            if ( DockPane.DockPanel.ShowDocumentIcon )
            {
                rectText.X += rectIcon.Width + DocumentIconGapRight;
                rectText.Y = rect.Y;
                rectText.Width = rect.Width - rectIcon.Width - DocumentIconGapLeft -
                    DocumentIconGapRight - DocumentTextGapRight;
                rectText.Height = rect.Height;
            }
            else
                rectText.Width = rect.Width - DocumentIconGapLeft - DocumentTextGapRight;

            Rectangle rectTab = DrawHelper.RtlTransform( this, rect );
            Rectangle rectBack = DrawHelper.RtlTransform( this, rect );
            rectBack.Width += rect.X;
            rectBack.X = 0;

            rectText = DrawHelper.RtlTransform( this, rectText );
            rectIcon = DrawHelper.RtlTransform( this, rectIcon );
            GraphicsPath path = GetTabOutline( tab, true, false );
            if ( DockPane.ActiveContent == tab.Content )
            {
                Color startColor = DockPane.DockPanel.Skin.DockPaneStripSkin.DocumentGradient.ActiveTabGradient.StartColor;
                Color endColor = DockPane.DockPanel.Skin.DockPaneStripSkin.DocumentGradient.ActiveTabGradient.EndColor;
                LinearGradientMode gradientMode = DockPane.DockPanel.Skin.DockPaneStripSkin.DocumentGradient.ActiveTabGradient.LinearGradientMode;
                g.FillPath( new LinearGradientBrush( rectBack, startColor, endColor, gradientMode ), path );
                g.DrawPath( PenDocumentTabActiveBorder, path );

                Color textColor = DockPane.DockPanel.Skin.DockPaneStripSkin.DocumentGradient.ActiveTabGradient.TextColor;
                if ( DockPane.IsActiveDocumentPane )
                    TextRenderer.DrawText( g, tab.Content.DockHandler.TabText, BoldFont, rectText, textColor, DocumentTextFormat );
                else
                    TextRenderer.DrawText( g, tab.Content.DockHandler.TabText, TextFont, rectText, textColor, DocumentTextFormat );
            }
            else
            {
                Color startColor = DockPane.DockPanel.Skin.DockPaneStripSkin.DocumentGradient.InactiveTabGradient.StartColor;
                Color endColor = DockPane.DockPanel.Skin.DockPaneStripSkin.DocumentGradient.InactiveTabGradient.EndColor;
                LinearGradientMode gradientMode = DockPane.DockPanel.Skin.DockPaneStripSkin.DocumentGradient.InactiveTabGradient.LinearGradientMode;
                g.FillPath( new LinearGradientBrush( rectBack, startColor, endColor, gradientMode ), path );
                g.DrawPath( PenDocumentTabInactiveBorder, path );

                Color textColor = DockPane.DockPanel.Skin.DockPaneStripSkin.DocumentGradient.InactiveTabGradient.TextColor;
                TextRenderer.DrawText( g, tab.Content.DockHandler.TabText, TextFont, rectText, textColor, DocumentTextFormat );
            }

            if ( rectTab.Contains( rectIcon ) && DockPane.DockPanel.ShowDocumentIcon )
                g.DrawIcon( tab.Content.DockHandler.Icon, rectIcon );
        }

        private void WindowList_Click( object sender, EventArgs e )
        {
            int x = 0;
            int y = ButtonWindowList.Location.Y + ButtonWindowList.Height;

            SelectMenu.Items.Clear();
            foreach ( TabVS2005 tab in Tabs )
            {
                IDockContent content = tab.Content;
                ToolStripItem item = SelectMenu.Items.Add( content.DockHandler.TabText, content.DockHandler.Icon.ToBitmap() );
                item.Tag = tab.Content;
                item.Click += new EventHandler( ContextMenuItem_Click );
            }
            SelectMenu.Show( ButtonWindowList, x, y );
        }

        private void ContextMenuItem_Click( object sender, EventArgs e )
        {
            ToolStripMenuItem item = sender as ToolStripMenuItem;
            if ( item != null )
            {
                IDockContent content = (IDockContent)item.Tag;
                DockPane.ActiveContent = content;
            }
        }

        private void SetInertButtons()
        {
            if ( Appearance == DockPane.AppearanceStyle.ToolWindow )
            {
                if ( m_buttonClose != null )
                    m_buttonClose.Left = -m_buttonClose.Width;

                if ( m_buttonWindowList != null )
                    m_buttonWindowList.Left = -m_buttonWindowList.Width;
            }
            else
            {
                ButtonClose.Enabled = DockPane.ActiveContent == null ? true : DockPane.ActiveContent.DockHandler.CloseButton;
                m_closeButtonVisible = DockPane.ActiveContent == null ? true : DockPane.ActiveContent.DockHandler.CloseButtonVisible;
                ButtonClose.Visible = m_closeButtonVisible;
                ButtonClose.RefreshChanges();
                ButtonWindowList.RefreshChanges();
            }
        }

        protected override void OnLayout( LayoutEventArgs levent )
        {
            if ( Appearance == DockPane.AppearanceStyle.Document )
            {
                LayoutButtons();
                OnRefreshChanges();
            }

            base.OnLayout( levent );
        }

        private void LayoutButtons()
        {
            Rectangle rectTabStrip = TabStripRectangle;

            // Set position and size of the buttons
            int buttonWidth = ButtonClose.Image.Width;
            int buttonHeight = ButtonClose.Image.Height;
            int height = rectTabStrip.Height - DocumentButtonGapTop - DocumentButtonGapBottom;
            if ( buttonHeight < height )
            {
                buttonWidth = buttonWidth * ( height / buttonHeight );
                buttonHeight = height;
            }
            Size buttonSize = new Size( buttonWidth, buttonHeight );

            int x = rectTabStrip.X + rectTabStrip.Width - DocumentTabGapLeft
                - DocumentButtonGapRight - buttonWidth;
            int y = rectTabStrip.Y + DocumentButtonGapTop;
            Point point = new Point( x, y );
            ButtonClose.Bounds = DrawHelper.RtlTransform( this, new Rectangle( point, buttonSize ) );

            // If the close button is not visible draw the window list button overtop.
            // Otherwise it is drawn to the left of the close button.
            if ( m_closeButtonVisible )
                point.Offset( -( DocumentButtonGapBetween + buttonWidth ), 0 );

            ButtonWindowList.Bounds = DrawHelper.RtlTransform( this, new Rectangle( point, buttonSize ) );
        }

        private void Close_Click( object sender, EventArgs e )
        {
            DockPane.CloseActiveContent();
        }

        protected internal override int HitTest( Point ptMouse )
        {
            if ( !TabsRectangle.Contains( ptMouse ) )
                return -1;

            foreach ( Tab tab in Tabs )
            {
                GraphicsPath path = GetTabOutline( tab, true, false );
                if ( path.IsVisible( ptMouse ) )
                    return Tabs.IndexOf( tab );
            }
            return -1;
        }

        protected override void OnMouseHover( EventArgs e )
        {
            int index = HitTest( PointToClient( Control.MousePosition ) );
            string toolTip = string.Empty;

            base.OnMouseHover( e );

            if ( index != -1 )
            {
                TabVS2005 tab = Tabs[ index ] as TabVS2005;
                if ( !String.IsNullOrEmpty( tab.Content.DockHandler.ToolTipText ) )
                    toolTip = tab.Content.DockHandler.ToolTipText;
                else if ( tab.MaxWidth > tab.TabWidth )
                    toolTip = tab.Content.DockHandler.TabText;
            }

            if ( m_toolTip.GetToolTip( this ) != toolTip )
            {
                m_toolTip.Active = false;
                m_toolTip.SetToolTip( this, toolTip );
                m_toolTip.Active = true;
            }

            // requires further tracking of mouse hover behavior,
            ResetMouseEventArgs();
        }

        protected override void OnRightToLeftChanged( EventArgs e )
        {
            base.OnRightToLeftChanged( e );
            PerformLayout();
        }
    }
}